package cn.opencodes.framework.core.log;

import java.lang.reflect.Method;
import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;

import cn.opencodes.framework.core.service.AlphaService;
import cn.opencodes.framework.core.utils.WebUtils;
import cn.opencodes.framework.core.vo.OperationLog;
import cn.opencodes.framework.tools.utils.JsonUtils;
import cn.opencodes.framework.tools.vo.RException;


/**
 * 操作日志，切面处理类
 * @author HJ
 */
@Aspect
@Order(0)
public class OperationAspect {
	@Autowired
	private AlphaService alphaSev;
	
	@Pointcut("@annotation(cn.opencodes.framework.core.log.SysOperationLog)")
	public void logPointCut() {}

	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		long beginTime = System.currentTimeMillis();
		Object result = null;
		int execState = 1;
		String errMsg = null;
		try {
			//执行方法
			result = point.proceed();
		} catch (Exception e) {
			execState = 0;
			errMsg = e.getMessage();
			throw new RException(errMsg, e);
		}finally{
			//执行时长(毫秒)
			long time = System.currentTimeMillis() - beginTime;
			//保存日志
			saveSysLog(point, time, execState, errMsg);
		}
		return result;
	}

	private void saveSysLog(ProceedingJoinPoint joinPoint, long time, int execState, String errMsg) throws Throwable {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = joinPoint.getTarget().getClass().getMethod(
        		signature.getName(), signature.getParameterTypes());
		SysOperationLog logAnno = method.getAnnotation(SysOperationLog.class);

		OperationLog operLog = new OperationLog();
		if(logAnno != null){
			//注解上的描述
			operLog.setOperation(logAnno.value());
		}
		//请求的方法名
		String className = joinPoint.getTarget().getClass().getSimpleName();
		String methodName = signature.getName();
		operLog.setMethod(className + "." + methodName);

		//请求的参数
		Object[] args = joinPoint.getArgs();
		try{
			String params = JsonUtils.toJson(args[0]);
			operLog.setParams(params);
		}catch (Exception e){

		}
		//用户名
		operLog.setUsername(WebUtils.getUser().getUsername());
		operLog.setTime(time);
		operLog.setCreateDate(new Date());
		operLog.setExecState(execState);
		operLog.setErrMsg(errMsg);
		//收集系统操作日志
		alphaSev.collect(operLog, OperationLog.class);
	}
}
